package com.campus.campusdelivery.service.impl;

import com.campus.campusdelivery.dto.MenuItemDto;
import com.campus.campusdelivery.dto.MenuItemRequest;
import com.campus.campusdelivery.entity.Category;
import com.campus.campusdelivery.entity.MenuItem;
import com.campus.campusdelivery.entity.Merchant;
import com.campus.campusdelivery.repository.CategoryRepository;
import com.campus.campusdelivery.repository.MenuItemRepository;
import com.campus.campusdelivery.repository.MerchantRepository;
import com.campus.campusdelivery.service.MenuItemService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class MenuItemServiceImpl implements MenuItemService {
    
    private final MenuItemRepository menuItemRepository;
    private final MerchantRepository merchantRepository;
    private final CategoryRepository categoryRepository;
    
    @Override
    public MenuItemDto getMenuItemById(Long id) {
        MenuItem menuItem = menuItemRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("菜品不存在"));
        return convertToDto(menuItem);
    }
    
    @Override
    public List<MenuItemDto> getMenuItemsByMerchant(Long merchantId) {
        return menuItemRepository.findByMerchantId(merchantId).stream()
                .map(this::convertToDto)
                .collect(Collectors.toList());
    }
    
    @Override
    public List<MenuItemDto> getAvailableMenuItemsByMerchant(Long merchantId) {
        return menuItemRepository.findAvailableMenuItemsByMerchant(merchantId).stream()
                .map(this::convertToDto)
                .collect(Collectors.toList());
    }
    
    @Override
    public Page<MenuItemDto> getMenuItemsByCategory(Long categoryId, Pageable pageable) {
        return menuItemRepository.findByCategoryId(categoryId, pageable).map(this::convertToDto);
    }
    
    @Override
    public Page<MenuItemDto> searchMenuItems(String keyword, Pageable pageable) {
        return menuItemRepository.findByKeyword(keyword, pageable).map(this::convertToDto);
    }
    
    @Override
    @Transactional
    public MenuItemDto createMenuItem(Long merchantId, MenuItemRequest request) {
        Merchant merchant = merchantRepository.findById(merchantId)
                .orElseThrow(() -> new RuntimeException("商家不存在"));
        
        MenuItem menuItem = new MenuItem();
        menuItem.setMerchant(merchant);
        menuItem.setName(request.getName());
        menuItem.setDescription(request.getDescription());
        menuItem.setImage(request.getImage());
        menuItem.setPrice(request.getPrice());
        menuItem.setStock(request.getStock());
        menuItem.setAvailable(true);
        menuItem.setSortOrder(request.getSortOrder() != null ? request.getSortOrder() : 0);
        
        if (request.getCategoryId() != null) {
            Category category = categoryRepository.findById(request.getCategoryId())
                    .orElseThrow(() -> new RuntimeException("分类不存在"));
            menuItem.setCategory(category);
        }
        
        menuItem = menuItemRepository.save(menuItem);
        return convertToDto(menuItem);
    }
    
    @Override
    @Transactional
    public MenuItemDto updateMenuItem(Long id, MenuItemRequest request) {
        MenuItem menuItem = menuItemRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("菜品不存在"));
        
        menuItem.setName(request.getName());
        menuItem.setDescription(request.getDescription());
        menuItem.setImage(request.getImage());
        menuItem.setPrice(request.getPrice());
        menuItem.setStock(request.getStock());
        menuItem.setSortOrder(request.getSortOrder() != null ? request.getSortOrder() : menuItem.getSortOrder());
        
        if (request.getCategoryId() != null) {
            Category category = categoryRepository.findById(request.getCategoryId())
                    .orElseThrow(() -> new RuntimeException("分类不存在"));
            menuItem.setCategory(category);
        }
        
        menuItem = menuItemRepository.save(menuItem);
        return convertToDto(menuItem);
    }
    
    @Override
    @Transactional
    public void deleteMenuItem(Long id) {
        MenuItem menuItem = menuItemRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("菜品不存在"));
        
        menuItemRepository.delete(menuItem);
    }
    
    @Override
    @Transactional
    public void toggleMenuItemAvailability(Long id) {
        MenuItem menuItem = menuItemRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("菜品不存在"));
        
        menuItem.setAvailable(!menuItem.getAvailable());
        menuItemRepository.save(menuItem);
    }
    
    @Override
    @Transactional
    public void updateMenuItemStock(Long id, Integer stock) {
        MenuItem menuItem = menuItemRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("菜品不存在"));
        
        menuItem.setStock(stock);
        menuItemRepository.save(menuItem);
    }
    
    @Override
    public Long getMenuItemsCount() {
        return menuItemRepository.count();
    }
    
    private MenuItemDto convertToDto(MenuItem menuItem) {
        MenuItemDto dto = new MenuItemDto();
        BeanUtils.copyProperties(menuItem, dto);
        
        // 设置关联信息
        dto.setMerchantId(menuItem.getMerchant().getId());
        dto.setMerchantName(menuItem.getMerchant().getShopName());
        
        if (menuItem.getCategory() != null) {
            dto.setCategoryId(menuItem.getCategory().getId());
            dto.setCategoryName(menuItem.getCategory().getName());
        }
        
        return dto;
    }
}
